package publish

import (
	"GoMaestro/internal/entity/app"
	"GoMaestro/internal/service"
	"github.com/gin-gonic/gin"
	"strings"
	"sync"
)

type PubApi struct {
	service.PubServiceImp
}

// Doing @Summary 发布入口
// @Accept json
// @Produce json
// @Router /v1/jen/pub/ [post]
func (p *PubApi) Doing(c *gin.Context) {
	var req PubRequest
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(400, gin.H{"error": "参数错误: " + err.Error()})
		return
	}
	taskID, App, err := p.Publishing(req.AppID, req.AutoDeploy, req.Env, req.Branch, req.Deploy_env)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, gin.H{"data": "success", "taskID": taskID, "App": App})
}

// BatchDoing 批量发布入口
// @Summary 批量发布入口
// @Accept json
// @Produce json
// @Router /v1/jen/pub/batch [post]
func (p *PubApi) BatchDoing(c *gin.Context) {
	var batchReq BatchPubRequest
	if err := c.ShouldBind(&batchReq); err != nil {
		c.JSON(400, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 设置默认最大并行数
	maxConcurrent := 5 // 默认值
	if batchReq.MaxParallel > 0 {
		maxConcurrent = batchReq.MaxParallel
	}

	// 创建任务通道
	tasks := make(chan PubRequest, len(batchReq.Requests))
	// 创建结果通道
	resultChan := make(chan gin.H, len(batchReq.Requests))

	// 创建等待组，用于等待所有工作协程完成
	var wg sync.WaitGroup

	// 先提前启动固定数量的工作协程
	for i := 0; i < maxConcurrent; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			// 工作协程从任务通道获取任务并处理，阻塞中，此时任务隧道无任务
			for req := range tasks {
				var taskID int
				var App *app.App
				var err error
				taskID, App, err = p.Publishing(req.AppID, req.AutoDeploy, req.Env, req.Branch, req.Deploy_env)

				// sdk的原因，引擎重启后首次并发构建会报错失效一次构建
				if err != nil && strings.Contains(err.Error(), "Don't have key \"Location\" in response of header") {
					taskID, App, err = p.Publishing(req.AppID, req.AutoDeploy, req.Env, req.Branch, req.Deploy_env)
				}
				if err != nil && !(strings.Contains(err.Error(), "Don't have key \"Location\" in response of header")) {
					resultChan <- gin.H{
						"status": "error",
						"appID":  req.AppID,
						"error":  err.Error(),
					}
				} else {
					resultChan <- gin.H{
						"status": "success",
						"appID":  req.AppID,
						"taskID": taskID,
						"App":    App,
					}
				}
			}
		}()
	}

	// 然后将所有请求发送到任务通道，提前启动的协程结束阻塞执行任务
	for _, req := range batchReq.Requests {
		tasks <- req
	}
	// 关闭任务通道，表示没有更多任务
	close(tasks)

	// 启动一个协程收集结果
	results := make([]gin.H, 0, len(batchReq.Requests))
	done := make(chan struct{})

	go func() {
		for i := 0; i < len(batchReq.Requests); i++ {
			result := <-resultChan
			results = append(results, result)
		}
		close(done)
	}()

	// 等待所有工作协程完成
	wg.Wait()
	// 等待结果收集完成
	<-done

	// 返回所有结果
	c.JSON(200, gin.H{
		"data":    "batch processing completed",
		"results": results,
	})
}
